package com.woyou.utils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.HttpHostConnectException;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.woyou.Constant;
import com.woyou.bean.CodeListResult;

import android.text.TextUtils;
import android.util.Log;

public class HttpUtil {
	private static final String TAG = "HttpUtil";
	
	
	
	public static List<HttpClient> clients = new ArrayList<HttpClient>();
	
	
	
//	static
//	{
//		openHttp(); 
//    }
	
	public static void closeHttp(){
//		if(httpClient !=null && httpClient.getConnectionManager()!=null){  
//            httpClient.getConnectionManager().shutdown();  
//            httpClient = null;
//        }
		for( HttpClient client :  clients ){
			if(client !=null && client.getConnectionManager()!=null){  
				client.getConnectionManager().shutdown();  
				client = null;
	        }
		}
	}
	
	private static HttpClient openHttp(){
//		if(httpClient == null){
			Log.i(TAG, "Create HttpClient...");  
	        HttpParams params = new BasicHttpParams();  
	        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);  
	        HttpProtocolParams.setContentCharset(params, HTTP.DEFAULT_CONTENT_CHARSET);  
	        HttpProtocolParams.setUseExpectContinue(params, true);  
	        SchemeRegistry schReg = new SchemeRegistry();  
	        schReg.register(new Scheme("http",PlainSocketFactory.getSocketFactory(),80));  
	        schReg.register(new Scheme("https",SSLSocketFactory.getSocketFactory(),443));  
	        ThreadSafeClientConnManager  conMgr = new ThreadSafeClientConnManager(params, schReg);  
	        HttpClient httpClient = new DefaultHttpClient(conMgr,params); 
	        clients.add(httpClient);
	        return httpClient;
//		}
	}
	/**
	 * GET请求
	 * @param request
	 * @return
	 * @throws IOException
	 * @throws HttpHostConnectException
	 */
	public static String httpString(String request) throws IOException, HttpHostConnectException{//mark!
		if(Constant.DBG) Log.d(TAG, "request: " + request);
		if(TextUtils.isEmpty(request)){
			return null;
		}
		HttpClient httpClient = openHttp(); 
		if(httpClient == null){
			throw new RuntimeException("please open http connect first");
		}
		
			HttpGet httpGet = new HttpGet(request); 
			// Set the timeout in milliseconds until a connection is established.  
			HttpParams httpParameters = new BasicHttpParams();
			// Set the default socket timeout (SO_TIMEOUT) // in 
//		    HttpConnectionParams.setConnectionTimeout(httpParameters, Constant.CONNECTION_TIMEOUT );
//		    HttpConnectionParams.setSoTimeout(httpParameters, Constant.SO_TIMEOUT);
		    httpGet.setParams(httpParameters);
			HttpResponse httpResponse = httpClient.execute(httpGet);
			int code = httpResponse.getStatusLine().getStatusCode();
			if (code == 200){
				String strResult = EntityUtils.toString(httpResponse.getEntity());
				if(Constant.DBG) Log.d(TAG, "strResult: " + strResult);
				return strResult;
			}
		return null;
	}
	
	/**
	 * post请求,参数是键值对
	 * @param request
	 * @return
	 * @throws IOException
	 * @throws HttpHostConnectException
	 */
	public static String httpStringPost(String request, Map<String, String> params) throws IOException, HttpHostConnectException{//mark!
		if(Constant.DBG) Log.d(TAG, "request: " + request);
		if(TextUtils.isEmpty(request)){
			return null;
		}
		HttpClient httpClient = openHttp(); 
		if(httpClient == null){
			throw new RuntimeException("please open http connect first");
		}
		
			HttpPost httpPost = new HttpPost(request);
			// Set the timeout in milliseconds until a connection is established.  
			// Set the default socket timeout (SO_TIMEOUT) // in 
//		    HttpConnectionParams.setConnectionTimeout(httpParameters, Constant.CONNECTION_TIMEOUT );
//		    HttpConnectionParams.setSoTimeout(httpParameters, Constant.SO_TIMEOUT);
			List <NameValuePair> paramsList = new ArrayList<NameValuePair>(); 
			for( String key : params.keySet() ){
				paramsList.add(new BasicNameValuePair(key, params.get(key)));
			}
			httpPost.setEntity(new UrlEncodedFormEntity(paramsList,HTTP.UTF_8));
			HttpResponse httpResponse = httpClient.execute(httpPost);
			int code = httpResponse.getStatusLine().getStatusCode();
			if (code == 200){
				String strResult = EntityUtils.toString(httpResponse.getEntity());
				Log.d(TAG, request +"\n "+ strResult);
				return strResult;
			}
		return null;
	}
	
	/**
	 * post请求,参数json字符串
	 * @param request
	 * @return
	 * @throws IOException
	 * @throws HttpHostConnectException
	 */
	public static String httpStringPost(String request, String json) throws IOException, HttpHostConnectException{//mark!
		if(Constant.DBG) Log.d(TAG, "request: " + request);
		if(TextUtils.isEmpty(request)){
			return null;
		}
		HttpClient httpClient = openHttp(); 
		if(httpClient == null){
			throw new RuntimeException("please open http connect first");
		}
		
			HttpPost httpPost = new HttpPost(request);
			// Set the timeout in milliseconds until a connection is established.  
			// Set the default socket timeout (SO_TIMEOUT) // in 
//		    HttpConnectionParams.setConnectionTimeout(httpParameters, Constant.CONNECTION_TIMEOUT );
//		    HttpConnectionParams.setSoTimeout(httpParameters, Constant.SO_TIMEOUT);
			StringEntity entity = new StringEntity(json, HTTP.UTF_8);
			httpPost.setEntity(entity);
			HttpResponse httpResponse = httpClient.execute(httpPost);
			int code = httpResponse.getStatusLine().getStatusCode();
			if (code == 200){
				String strResult = EntityUtils.toString(httpResponse.getEntity());
				Log.d(TAG, request +"\n "+ strResult);
				return strResult;
			}
		return null;
	}
	
	
	public static <T> List<T> httpList(String request , Class<T> c,String tag) throws IOException, JSONException{
		String res = httpString(request);
		if(TextUtils.isEmpty(res)){
			return null;
		}
		JSONObject o = new JSONObject(res);
		JSONArray array = o.getJSONArray(tag);
		return JsonUtils.getInstance(c, array);
	}
	
	public static <T> List<T> httpList4Result(String result, Class<T> c,String tag)throws IOException, JSONException{
		String res = result;
		if(TextUtils.isEmpty(res)){
			return null;
		}
		JSONObject o = new JSONObject(res);
		JSONArray array = o.getJSONArray(tag);
		return JsonUtils.getInstance(c, array);
	}
	
	public static <T> T httpObject(String request ,Class<T> c) throws IOException, JSONException{//mark
		String res = httpString(request);
		if(TextUtils.isEmpty(res)){
			return null;
		}
		return JsonUtils.getInstance(c, new JSONObject(res));
	}
	/**
	 * post请求
	 * @param request
	 * @param c
	 * @param params
	 * @return
	 * @throws IOException
	 * @throws JSONException
	 */
	public static <T> T httpObjectPost(String request ,Class<T> c, Map<String,String> params) throws IOException, JSONException{//mark
		long currentTimeMillis = System.currentTimeMillis();
		String res = httpStringPost(request, params);
		long time = System.currentTimeMillis() - currentTimeMillis;
		Log.i(TAG, "httpStringPost花了"+time+"毫秒");
		if(TextUtils.isEmpty(res)){
			return null;
		}
		return JsonUtils.getInstance(c, new JSONObject(res));
	}
	
	
	public static <T> CodeListResult<T> httpListResult(String request , String tag ,Class<T> c) throws IOException, JSONException, HttpHostConnectException{
		String res = httpString(request);
		if(TextUtils.isEmpty(res)){
			return null;
		}
		JSONObject o = new JSONObject(res);
		JSONArray array = o.getJSONArray(tag);
		int page;
		if (o.has("page")) {
			page = o.getInt("page");
		} else {
			page = 0;
		}
		List<T> list = JsonUtils.getInstance(c, array);
		CodeListResult<T> listResult = new CodeListResult<T>();
		listResult.list = list;
		listResult.page = page;
		return listResult;
	}
	
}
